package cn.fl.institution.controller;

import cmm.mid.core.framework.constant.tripartite.InterfaceConstants;
import cmm.mid.core.framework.dto.DataResultDTO;
import cmm.mid.core.framework.dto.MessageDTO;
import cmm.mid.core.framework.page.DataResultVO;
import cn.cmm.base.framework.constant.BaseConstant;
import cn.cmm.base.framework.exception.BaseException;
import cn.cmm.base.framework.utils.BaseLogUtils;
import cn.cmm.base.framework.utils.CollectionUtils;
import cn.cmm.base.framework.utils.DecimalUtils;
import cn.cmm.base.framework.utils.StringUtils;
import cn.cmm.cache.framework.constant.CacheConstant;
import cn.cmm.cache.framework.service.ICacheService;
import cn.fl.customer.service.ICstBscInfoService;
import cn.fl.customer.service.ICstNpBscInfoService;
import cn.fl.customer.vo.CstNpBscInfoVO;
import cn.fl.framework.base.context.CurrentThreadContext;
import cn.fl.framework.constant.DictionaryConstant;
import cn.fl.institution.api.IXbflInsApiService;
import cn.fl.project.api.IPrjCstAccInfoApiService;
import cn.fl.project.condition.PrjCstAccInfoQueryCondition;
import cn.fl.project.constant.PrjBscInfoConstant;
import cn.fl.project.service.IPrjBscInfoService;
import cn.fl.project.service.IPrjCstAccInfoService;
import cn.fl.project.vo.PrjBscInfoVO;
import cn.fl.project.vo.PrjCstAccInfoVO;
import cn.fl.system.constant.SysLogConstant;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import pam.xbfl.facade.api.IXbflApiService;
import pam.xbfl.facade.dto.ApplyLoanDTO;
import pam.xbfl.facade.dto.FileDTO;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @Description: 项目基础信息表 控制层 兴邦金租
 */
@Controller
@RequestMapping("/institution/xbfl")
public class PrjBscInfoInsXBFLController {
    private static final Logger logger = LoggerFactory.getLogger(PrjBscInfoInsXBFLController.class);

    @Autowired
    private IPrjBscInfoService prjBscInfoService; // 项目基础信息表

    @Autowired
    private IPrjCstAccInfoApiService prjCstAccInfoApiService; // 项目客户账户信息表

    @Autowired
    private ICstBscInfoService cstBscInfoService; // 客户基础信息

    @Autowired
    private ICstNpBscInfoService cstNpBscInfoService; // 自然人信息

    @Autowired
    private IPrjCstAccInfoService prjCstAccInfoService;//项目客户基础信息表

    @Autowired
    private IXbflInsApiService xbflInsApiService;

    @Autowired
    private ICacheService cacheService;

    @Autowired
    private IXbflApiService xbflApiService;

    /**
     * 获取验证码
     */
    @RequestMapping(value = "/getVerificationCode.do", method = {RequestMethod.POST})
    @ResponseBody
    public Object getVerificationCode (Long prjId,PrjCstAccInfoQueryCondition prjCstAccInfoQC) throws BaseException {
        DataResultVO result = new DataResultVO(BaseConstant.IS_YESNO_YES, "四要素校验通过");
        BaseLogUtils.info(logger, "save", "兴邦金租获取验证码 四要素信息： prjCstAccInfoQC = " + JSONObject.toJSONString(prjCstAccInfoQC));
        // 开户银行
        if(StringUtils.isBlank(prjCstAccInfoQC.getBkCd()) || StringUtils.isBlank(prjCstAccInfoQC.getBkNm())){
            result.setSuccess(BaseConstant.IS_YESNO_NO);
            result.setInfo("请输入开户银行!");
            return result;
        }
        // 银行账号
        if(StringUtils.isBlank(prjCstAccInfoQC.getAccNo())){
            result.setSuccess(BaseConstant.IS_YESNO_NO);
            result.setInfo("请输入银行账号!");
            return result;
        }
        // 客户手机号
        if(StringUtils.isBlank(prjCstAccInfoQC.getMp())){
            result.setSuccess(BaseConstant.IS_YESNO_NO);
            result.setInfo("请输入手机号!");
            return result;
        }
        try{
            PrjCstAccInfoQueryCondition prjCstAccInfo = new PrjCstAccInfoQueryCondition();
            prjCstAccInfo.setPrjId(prjId);
            prjCstAccInfo.setIsDel(BaseConstant.IS_YESNO_NO);
            prjCstAccInfo.setInsCode(PrjBscInfoConstant.PRJ_INS_CODE_XBFL);
            List<PrjCstAccInfoVO> prjCstAccInfoVOS = this.prjCstAccInfoService.searchList(prjCstAccInfo);
            if (CollectionUtils.isNotEmpty(prjCstAccInfoVOS)) {
                PrjCstAccInfoVO prjCstAccInfoVO = prjCstAccInfoVOS.get(0);
                BaseLogUtils.info(logger, "save", "兴邦金租获取验证码 项目基本信息： prjBscInfoVO = " + JSONObject.toJSONString(prjCstAccInfo));
                prjCstAccInfoQC.setId(prjCstAccInfoVO.getId());
            }
            // 四要素验证
            prjCstAccInfoQC.setCertTypCd(DictionaryConstant.CODE_CERT_TYP_CD_0);
            prjCstAccInfoQC.setBkNo(prjCstAccInfoQC.getBkCd());
            prjCstAccInfoQC.setAccNm(prjCstAccInfoQC.getCstNm());
            prjCstAccInfoQC.setInsCode(PrjBscInfoConstant.PRJ_INS_CODE_XBFL);
            BaseLogUtils.info(logger, "save", "兴邦金租获取验证码 页面提交的项目客户信息： " + JSONObject.toJSONString(prjCstAccInfoQC));
            DataResultDTO resultDTO = this.prjCstAccInfoApiService.snVerifyModifyPrjAccInfo(prjCstAccInfoQC);

            // 判断四要素校验结果
            BaseLogUtils.info(logger, "save", "兴邦金租获取验证码 四要素验证结果 ： " + JSONObject.toJSONString(resultDTO));
            String chkRstCd = null, rstDesc = null;
            String bankCardType = null;
            if(resultDTO != null && StringUtils.isNotEmpty(resultDTO.getCode())
                    && Integer.valueOf(resultDTO.getCode()) != BaseConstant.IS_YESNO_YES) {
                chkRstCd = resultDTO.getCode();
                rstDesc = resultDTO.getInfo();
            }else if(resultDTO != null && resultDTO.getData() != null) {
                @SuppressWarnings("unchecked")
                Map<String, String> ckResMap = (Map<String, String>) resultDTO.getData();
                chkRstCd = ckResMap.get("chkRstCd");
                rstDesc = ckResMap.get("rstDesc");
                bankCardType = ckResMap.get("bankCardType");
            }
            if(chkRstCd == null || Integer.valueOf(chkRstCd) != BaseConstant.IS_YESNO_YES) {
                result.setSuccess(BaseConstant.IS_YESNO_NO);
                result.setInfo("四要素信息有误，请修改");
                return result;
            }
            if ("1".equals(bankCardType)){
                result.setSuccess(BaseConstant.IS_YESNO_NO);
                result.setInfo("不支持此类银行卡，请更换为借记卡");
                return result;
            }
            // 发送验证码
            DataResultDTO dataResultDTO = this.xbflInsApiService.createAccount(String.valueOf(prjCstAccInfoQC.getCstId()), String.valueOf(prjId), prjCstAccInfoQC.getBkCd(), prjCstAccInfoQC.getAccNo(), prjCstAccInfoQC.getCertNo(), prjCstAccInfoQC.getMp());
            if(dataResultDTO!=null){
                if(BaseConstant.IS_YESNO_YES_NM.equals(dataResultDTO.getCode())){
                    result.setSuccess(BaseConstant.IS_YESNO_YES);
                    result.setInfo(dataResultDTO.getInfo());
                    result.setData(dataResultDTO.getData());
                }else{
                    result.setSuccess(BaseConstant.IS_YESNO_NO);
                    result.setInfo(dataResultDTO.getInfo());
                }
            }else{
                result.setSuccess(BaseConstant.IS_YESNO_NO);
                result.setInfo("验证码获取失败，请重新尝试；");
            }
        }catch (BaseException ex) {
            result.setSuccess(BaseConstant.IS_YESNO_NO);
            result.setInfo(ex.getMessage());
            BaseLogUtils.error(logger, "save", "兴邦金租获取验证码失败 " + ex.getMessage());
            ex.printStackTrace();
        }
        catch (Exception ex) {
            result.setSuccess(BaseConstant.IS_YESNO_NO);
            result.setInfo("获取验证码失败!");
            BaseLogUtils.error(logger, "save", "兴邦金租获取验证码失败 " + ex.getMessage());
            ex.printStackTrace();
        }
        return result;
    }
    /**
     * 保存 项目客户信息。
     */
    @RequestMapping(value = "/save.do", method = {RequestMethod.POST})
    @ResponseBody
    public Object save (Long prjId,PrjCstAccInfoQueryCondition prjCstAccInfoQC) throws BaseException {
        DataResultVO result = new DataResultVO(BaseConstant.IS_YESNO_YES, "四要素校验通过");
        BaseLogUtils.info(logger, "save", "兴邦金租立项保存 四要素信息： prjCstAccInfoQC = " + JSONObject.toJSONString(prjCstAccInfoQC));
        // 开户银行
        if(StringUtils.isBlank(prjCstAccInfoQC.getBkCd()) || StringUtils.isBlank(prjCstAccInfoQC.getBkNm())){
            return new DataResultVO(BaseConstant.IS_YESNO_NO, "请输入开户银行!");
        }
        // 银行账号
        if(StringUtils.isBlank(prjCstAccInfoQC.getAccNo())){
            return new DataResultVO(BaseConstant.IS_YESNO_NO, "请输入银行账号!");
        }
        // 客户手机号
        if(StringUtils.isBlank(prjCstAccInfoQC.getMp())){
            return new DataResultVO(BaseConstant.IS_YESNO_NO, "请输入手机号!");
        }
        // 身份证有效期
        if(StringUtils.isBlank(prjCstAccInfoQC.getCertValidEDt())){
            return new DataResultVO(BaseConstant.IS_YESNO_NO, "请输入身份证有效期!");
        }
        if (StringUtils.isBlank(prjCstAccInfoQC.getNation())) {
            return new DataResultVO(BaseConstant.IS_YESNO_NO, "请选择民族!");
        }
        if (StringUtils.isBlank(prjCstAccInfoQC.getMonthInc())) {
            return new DataResultVO(BaseConstant.IS_YESNO_NO, "请输入月收入!");
        }
        if(Double.parseDouble(prjCstAccInfoQC.getMonthInc()) <= 0 || Double.parseDouble(prjCstAccInfoQC.getMonthInc()) > 100000){
            return new DataResultVO(BaseConstant.IS_YESNO_NO, "个人月收入请输入大于0且小于10万的数字!");
        }
        if (StringUtils.isBlank(prjCstAccInfoQC.getPostProvince())) {
            return new DataResultVO(BaseConstant.IS_YESNO_NO, "居住省空!");
        }
        if (StringUtils.isBlank(prjCstAccInfoQC.getPostCity())) {
            return new DataResultVO(BaseConstant.IS_YESNO_NO, "居住市为空!");
        }
        if (StringUtils.isBlank(prjCstAccInfoQC.getPostAddr())) {
            return new DataResultVO(BaseConstant.IS_YESNO_NO, "居住地址详情为空!");
        }
        if (StringUtils.isBlank(prjCstAccInfoQC.getDomicileProvince())) {
            return new DataResultVO(BaseConstant.IS_YESNO_NO, "户籍所在地省为空!");
        }
        if (StringUtils.isBlank(prjCstAccInfoQC.getDomicleCity())) {
            return new DataResultVO(BaseConstant.IS_YESNO_NO, "户籍所在地市为空!");
        }
        try{
            //修改自然信息
            this.modifyCstNpBscInfo(prjCstAccInfoQC);
            boolean isNeedSign = true;  // 是否需要签约绑卡
//            PrjCstAccInfoVO prjCstAccInfo = this.prjCstAccInfoService.selectByPrjId(prjId);
            PrjCstAccInfoVO prjCstAccInfo = null;
            PrjCstAccInfoQueryCondition prjCstAccInfoQueryCondition = new PrjCstAccInfoQueryCondition();
            prjCstAccInfoQueryCondition.setPrjId(prjId);
            prjCstAccInfoQueryCondition.setIsDel(BaseConstant.IS_YESNO_NO);
            prjCstAccInfoQueryCondition.setInsCode(PrjBscInfoConstant.PRJ_INS_CODE_XBFL);
            List<PrjCstAccInfoVO> prjCstAccInfoVOS = this.prjCstAccInfoService.searchList(prjCstAccInfoQueryCondition);
            if (CollectionUtils.isNotEmpty(prjCstAccInfoVOS)) {
                prjCstAccInfo = prjCstAccInfoVOS.get(0);
            }
            BaseLogUtils.info(logger, "save", "兴邦金租立项保存 项目基本信息： prjBscInfoVO = " + JSONObject.toJSONString(prjCstAccInfo));
            if(cacheService.keyExists("兴邦银行发送短信特殊处理缓存标识:" + prjId)) {
                String xbflCode = (String) this.cacheService.get("兴邦银行发送短信特殊处理缓存标识:" + prjId, CacheConstant.CACHE_OPERATION_REMOTE);
                BaseLogUtils.info(logger, "save", "兴邦银行发送短信特殊处理缓存标识:" + prjId + " xbflCode :" + xbflCode);
                if ("393219".equals(xbflCode)) {
                    isNeedSign = false;
                    if (null != prjCstAccInfo && null != prjCstAccInfo.getId()) {
                        prjCstAccInfoQC.setId(prjCstAccInfo.getId());
                        if (!(prjCstAccInfoQC.getCstNm().equals(prjCstAccInfo.getCstNm())
                                && prjCstAccInfoQC.getAccNo().equals(prjCstAccInfo.getAccNo())
                                && prjCstAccInfoQC.getMp().equals(prjCstAccInfo.getMp()))) {
                            isNeedSign = true;
                            prjCstAccInfoQC.setAccResCd("0");
                            cacheService.set("兴邦银行发送短信特殊处理缓存标识:" + prjId, "0");
                        }
                    }
                }
            }
            if (null != prjCstAccInfo && null != prjCstAccInfo.getId()) {
                prjCstAccInfoQC.setId(prjCstAccInfo.getId());
                if(null != prjCstAccInfo.getAccResCd() && "1".equals(prjCstAccInfo.getAccResCd())){
                    isNeedSign = false;
                }
                if (!(prjCstAccInfoQC.getCstNm().equals(prjCstAccInfo.getCstNm())
                        && prjCstAccInfoQC.getAccNo().equals(prjCstAccInfo.getAccNo())
                        && prjCstAccInfoQC.getMp().equals(prjCstAccInfo.getMp()))) {
                    isNeedSign = true;
                    prjCstAccInfoQC.setAccResCd("0");
                    cacheService.set("兴邦银行发送短信特殊处理缓存标识:" + prjId, "0");
                }
            }
            if (null != prjCstAccInfo && null != prjCstAccInfo.getId()) {
                prjCstAccInfoQC.setId(prjCstAccInfo.getId());
            }
            BaseLogUtils.info(logger, "save", "兴邦金租立项保存 项目基本信息： isNeedSign = " + isNeedSign);
            if(isNeedSign){
                // 短信验证码
                if(StringUtils.isBlank(prjCstAccInfoQC.getPhoneCode())){
                    result.setSuccess(BaseConstant.IS_YESNO_NO);
                    result.setInfo("请输入短信验证码!");
                    return result;
                }
            }
            prjCstAccInfoQC.setInsCode(PrjBscInfoConstant.PRJ_INS_CODE_XBFL);
            // 保存项目客户信息，包含四要素验证
            prjCstAccInfoQC.setCertTypCd(DictionaryConstant.CODE_CERT_TYP_CD_0);
            prjCstAccInfoQC.setBkNo(prjCstAccInfoQC.getBkCd());
            prjCstAccInfoQC.setAccNm(prjCstAccInfoQC.getCstNm());


            BaseLogUtils.info(logger, "save", "兴邦金租立项保存 页面提交的项目客户信息： " + JSONObject.toJSONString(prjCstAccInfoQC));
            DataResultDTO resultDTO = this.prjCstAccInfoApiService.modifyPrjAccInfo(prjCstAccInfoQC); //

            // 判断四要素校验结果
            BaseLogUtils.info(logger, "save", "兴邦金租立项保存 四要素验证结果 ： " + JSONObject.toJSONString(resultDTO));
            String chkRstCd = null, rstDesc = null;
            String bankCardType = null;
            Map<String, String> ckResMap = null;
            if (resultDTO != null){
                if("0".equals(resultDTO.getCode())) {
                    result.setSuccess(BaseConstant.IS_YESNO_NO);
                    result.setInfo(rstDesc);
                    return result;
                }
                if (resultDTO.getData() != null){
                    ckResMap = (Map<String, String>) resultDTO.getData();
                    chkRstCd = ckResMap.get("chkRstCd");
                    rstDesc = ckResMap.get("rstDesc");
                    bankCardType = ckResMap.get("bankCardType");

                    //验证返回结果成功
                    if(!"1".equals(chkRstCd)) {
                        result.setSuccess(BaseConstant.IS_YESNO_NO);
                        result.setInfo(rstDesc);
                        return result;
                    }
                    if (!"0".equals(bankCardType)){
                        result.setSuccess(BaseConstant.IS_YESNO_NO);
                        result.setInfo("不支持此类银行卡，请更换为借记卡");
                        return result;
                    }

                }

            }else {
                result.setSuccess(BaseConstant.IS_YESNO_NO);
                result.setInfo(resultDTO.getInfo());
                return result;
            }
            result.setInfo("客户信息保存成功！");
            if(isNeedSign) {
                // 签约绑卡
                DataResultDTO dataResultDTO = this.xbflInsApiService.signAccount(String.valueOf(prjCstAccInfoQC.getCstId()), String.valueOf(prjId), prjCstAccInfoQC.getBkCd(), prjCstAccInfoQC.getAccNo(), prjCstAccInfoQC.getCertNo(), prjCstAccInfoQC.getMp(), prjCstAccInfoQC.getPhoneCode());
                if (dataResultDTO != null) {
                    if (BaseConstant.IS_YESNO_YES_NM.equals(dataResultDTO.getCode())) {//签约绑卡成功
                        PrjBscInfoVO prjBscInfoVO = this.prjBscInfoService.selectById(Long.valueOf(prjCstAccInfo.getPrjId()));
                        result.setSuccess(BaseConstant.IS_YESNO_YES);
                        result.setInfo("绑卡成功，客户在+" + prjBscInfoVO.getFundRasInsNm() + "+还款银行卡已绑卡；");
                    } else {//签约绑卡失败
                        result.setSuccess(BaseConstant.IS_YESNO_NO);
                        result.setInfo(dataResultDTO.getInfo());
                    }
                } else {//签约绑卡失败
                    result.setSuccess(BaseConstant.IS_YESNO_NO);
                    result.setInfo("签约绑卡失败，请联系客户核实银行卡和预留手机号信息");
                }
            }
        }catch (BaseException ex) {
            result.setSuccess(BaseConstant.IS_YESNO_NO);
            result.setInfo(ex.getMessage());
            BaseLogUtils.error(logger, "save", "兴邦金租立项保存失败 " + ex.getMessage());
            ex.printStackTrace();
        }
        catch (Exception ex) {
            result.setSuccess(BaseConstant.IS_YESNO_NO);
            result.setInfo("保存失败!");
            BaseLogUtils.error(logger, "save", "兴邦金租立项保存失败 " + ex.getMessage());
            ex.printStackTrace();
        }

        return result;
    }
    /**
      * @Author yangzhongkun
      * @params [prjCstAccInfoQC]
      * @Description 兴邦金租 修改自然信息
      * @Date 2020/8/28 11:14
      * @return void
      **/
    private void modifyCstNpBscInfo(PrjCstAccInfoQueryCondition prjCstAccInfoQC) throws BaseException {

        //根据客户id查询 客户信息
        BaseLogUtils.newLogger("兴邦金租根据cstId查询自然人信息Start:cstId={}",prjCstAccInfoQC.getCstId()).info();
        CstNpBscInfoVO cstNpBscInfoVO = this.cstNpBscInfoService.selectById(prjCstAccInfoQC.getCstId());
        BaseLogUtils.newLogger("兴邦金租根据cstId查询自然人信息End:cstId={},cstNpBscInfoVO={}",prjCstAccInfoQC.getCstId(),JSONObject.toJSONString(cstNpBscInfoVO)).info();
        if(null != cstNpBscInfoVO){
            //修改标识
            boolean flag = false;
            CstNpBscInfoVO npBscInfoVO = new CstNpBscInfoVO();
            npBscInfoVO.setId(cstNpBscInfoVO.getId());
            //现住地址-省
            if(!Objects.equals(prjCstAccInfoQC.getPostProvince(),cstNpBscInfoVO.getPostProvince())){
                npBscInfoVO.setPostProvince(prjCstAccInfoQC.getPostProvince());
                flag = true;
            }
            //现住地址-市
            if(!Objects.equals(prjCstAccInfoQC.getPostCity(),cstNpBscInfoVO.getPostCity())){
                npBscInfoVO.setPostCity(prjCstAccInfoQC.getPostCity());
                flag = true;
            }
            //现住地址详情
            if(!Objects.equals(prjCstAccInfoQC.getPostAddr(),cstNpBscInfoVO.getPostAddr())){
                npBscInfoVO.setPostAddr(prjCstAccInfoQC.getPostAddr());
                flag = true;
            }
            //户籍地址-省
            if(!Objects.equals(prjCstAccInfoQC.getDomicileProvince(),cstNpBscInfoVO.getDomicileProvince())){
                npBscInfoVO.setDomicileProvince(prjCstAccInfoQC.getDomicileProvince());
                flag = true;
            }
            //户籍地址-市
            if(!Objects.equals(prjCstAccInfoQC.getDomicleCity(),cstNpBscInfoVO.getDomicleCity())){
                npBscInfoVO.setDomicleCity(prjCstAccInfoQC.getDomicleCity());
                flag = true;
            }
            //民族
            if(!Objects.equals(prjCstAccInfoQC.getNation(),cstNpBscInfoVO.getNation())){
                npBscInfoVO.setNation(prjCstAccInfoQC.getNation());
                flag = true;
            }
            //年收入
            Long mrIncMoney = DecimalUtils.convertYuanToFen(Double.valueOf(prjCstAccInfoQC.getMonthInc())); // 月收入转为分
            Double yrInc = DecimalUtils.mul(mrIncMoney.doubleValue(),12d); // 月收入转换年收入
            if(!Objects.equals(yrInc.longValue(),cstNpBscInfoVO.getYrInc())){
                npBscInfoVO.setYrInc(yrInc.longValue());
                flag = true;
            }
            //有信息变更 更新变更时间和变更人
            if(flag){
                npBscInfoVO.setMdfTm(new Date());//更新时间
                npBscInfoVO.setMdfUsrId(CurrentThreadContext.getCurrentUserId());//更新人
                BaseLogUtils.newLogger("兴邦金租修改自然人信息Start:cstId={},npBscInfoVO={}",prjCstAccInfoQC.getCstId(),JSON.toJSONString(npBscInfoVO)).info();
                boolean modify = this.cstNpBscInfoService.modify(npBscInfoVO);
                BaseLogUtils.newLogger("兴邦金租修改自然人信息End:cstId={},modifyResult={},npBscInfoVO={}",prjCstAccInfoQC.getCstId(),modify,JSON.toJSONString(npBscInfoVO)).info();
            }
        }

    }
    @RequestMapping(value = "/getPath.do", method = {RequestMethod.GET, RequestMethod.POST })
    @ResponseBody
    public DataResultVO getPath(HttpServletRequest request, HttpServletResponse response) throws BaseException {
        BaseLogUtils.newServiceLogger("进入获取兴邦合同链接方法Start").info();
        Long startTm = System.currentTimeMillis();
        DataResultVO result = new DataResultVO(BaseConstant.IS_YESNO_YES, SysLogConstant.LOG_CMM_OPERATE_SUCC);
        String prjId = request.getParameter("prjId");
        String fundRasInsId = request.getParameter("fundRasInsId");
        if (StringUtils.isEmpty(prjId) || StringUtils.isEmpty(fundRasInsId)) {
            result.setSuccess(BaseConstant.IS_YESNO_NO);
            result.setInfo("参数不可为空");
        }
        BaseLogUtils.newServiceLogger("兴邦-获取合同下载链接Start prjId:" + prjId + ",fundRasInsId:" + fundRasInsId).info();
        MessageDTO<InterfaceConstants.AuditResult> messageDTO = this.xbflApiService.downLoanContract(Long.valueOf(fundRasInsId), Long.valueOf(prjId));
        BaseLogUtils.newServiceLogger("兴邦-获取合同下载链接End prjId：" + prjId + "," + JSON.toJSONString(messageDTO)).info();
        if (messageDTO == null) {
            result.setSuccess(BaseConstant.IS_YESNO_NO);
            result.setInfo("获取合同下载链接失败.");
        } else if (!messageDTO.isSuccess() || null == messageDTO.getData() || !InterfaceConstants.AuditResult.pass.key().equals(messageDTO.getData().toString())
                || StringUtils.isEmpty(messageDTO.getContent())) {
            result.setSuccess(BaseConstant.IS_YESNO_NO);
            if (StringUtils.isNotEmpty(messageDTO.getMessage())) {
                result.setInfo(messageDTO.getMessage());
            } else {
                result.setInfo("获取合同下载链接失败.");
            }
        } else {
            //合同下载链接
            result.setData(messageDTO.getContent());
        }
        Long endTm = System.currentTimeMillis();
        BaseLogUtils.newServiceLogger("进入获取兴邦合同链接方法End!耗时:" + (endTm - startTm)).info();
        return result;
    }

    @RequestMapping(value = "/zipDownloadByUrl.do", method = {RequestMethod.GET, RequestMethod.POST})
    public ModelAndView zipDownloadByUrl(HttpServletRequest request, HttpServletResponse response) {
        BaseLogUtils.newServiceLogger("进入下载兴邦合同文件方法Start").info();
        String urls = request.getParameter("urls");
        BaseLogUtils.newServiceLogger("进入下载兴邦合同文件方法 urls:" + urls).info();
        //URL地址
        List<FileDTO> files = null;
        if (StringUtils.isNotEmpty(urls)) {
            ApplyLoanDTO applyLoanDTO = JSONObject.parseObject(urls, ApplyLoanDTO.class);
            BaseLogUtils.newServiceLogger("进入下载兴邦合同文件方法 applyLoanDTO:" + JSON.toJSONString(applyLoanDTO)).info();
            if (applyLoanDTO != null && CollectionUtils.isNotEmpty(applyLoanDTO.getFiles())) {
                //URL地址
                files = applyLoanDTO.getFiles();
            }
        }
        //ZIP文件名
        String uuid = UUID.randomUUID().toString().replace("-", "");
        String tmpZipFileName = uuid + ".zip";
        try {
            //响应头的设置
            response.reset();
            response.setContentType("application/x-msdownload;");
            response.setHeader("Content-Disposition", "attachment; filename=" + tmpZipFileName);
            response.setCharacterEncoding("UTF-8");
            //设置压缩流：直接写入response，实现边压缩边下载
            ZipOutputStream zipos = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream()));
            DataOutputStream os = null;
            try {
                //循环将文件写入压缩流
                if (CollectionUtils.isNotEmpty(files)) {
                    for (int i = 0; i < files.size(); i++) {
                        FileDTO fileDTO = files.get(i);
                        //合同下载地址
                        String fileUrl = fileDTO.getFileUrl();
                        String fileName = fileDTO.getFileName();
                        if (StringUtils.isNotEmpty(fileUrl)) {
                            String urlStr = encodeFileUrl(fileUrl);
                            BaseLogUtils.newServiceLogger("url转码 fileUrl:" + urlStr).info();
                            URL url = new URL(urlStr);
                            URLConnection conn = url.openConnection();
                            conn.setConnectTimeout(10000);
                            conn.setReadTimeout(60000);
                            InputStream inputStream = conn.getInputStream();
                            //添加ZipEntry，并ZipEntry中写入文件流
                            zipos.putNextEntry(new ZipEntry(fileName));
                            os = new DataOutputStream(zipos);
                            byte[] buff = new byte[1024];
                            int bytesRead;
                            while (-1 != (bytesRead = inputStream.read(buff, 0, buff.length))) {
                                os.write(buff, 0, bytesRead);
                            }
                            //关闭此文件流
                            inputStream.close();
                            //关闭当前ZIP项，并将流放置到写入的位置。下一个条目。
                            zipos.closeEntry();
                        }
                    }
                }
            } catch (IOException e) {
                BaseLogUtils.newServiceLogger("兴邦-下载打包文件失败!" + e).info();
            } finally {
                //释放资源
                if (null != os) {
                    os.flush();
                    os.close();
                }
                if (null != zipos) {
                    zipos.close();
                }
            }
        } catch (Exception e) {
            BaseLogUtils.newServiceLogger("兴邦-下载打包文件失败!" + e).info();
        }
        return null;
    }

    /**
     * 编码URL路径中文
     *
     * @param url
     * @return
     */
    private String encodeFileUrl(String url) {
        if (StringUtils.isNotEmpty(url)) {
            Matcher matcher = Pattern.compile("[^\\x00-\\xff]").matcher(url);
            while (matcher.find()) {
                String tmp = matcher.group();
                try {
                    url = url.replaceAll(tmp, URLEncoder.encode(tmp, "UTF-8"));
                } catch (UnsupportedEncodingException e) {
                    BaseLogUtils.newServiceLogger("兴邦-下载文件URL转码失败!" + e).info();
                }
            }
        }
        return url;
    }

}
